<?php
/**
 * Created by PhpStorm.
 * User: van404
 * Date: 2017/7/15
 * Time: 21:31
 */

namespace Controllers;


use GuzzleHttp\Client;
use GuzzleHttp\Pool;
use GuzzleHttp\Psr7\Request;
use Monolog\Logger as Monolog;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Slim\Collection;


class ChatController
{
    protected $ci;
    /**
     * @var Client
     */
    protected $http;

    /**
     * @var array
     */
    protected $files;

    /**
     * @var array
     */
    protected $settings;

    /**
     * @var Monolog
     */
    protected $logger;

    /**
     * @var Collection
     */
    protected $messages;

    public function __construct(ContainerInterface $ci)
    {
        $this->ci = $ci;

        $this->http = $this->ci->get('http');

        $this->settings = $this->ci->get('settings');

        $this->files = $this->ci->get('files');

        $this->logger = $this->ci->get('logger');

        $this->messages = new Collection();
    }

    public function chat(ServerRequestInterface $request, ResponseInterface $response)
    {
        $queries = $request->getQueryParams();
//        $this->dl('http://upload.api.weibo.com/2/mss/msget?source=351354573&fid=4130214550435286', 'mp3');
//        exit;
        $ary = function ($status, $content, $type = 'txt') {
            return array(
                'status' => $status,
                'type' => $type,
                'content' => $content
            );
        };
        if (!empty($queries['msg'])) {
            if (($this->step1($queries['msg'])) !== false) {
                $msg = $this->step2();
                if (!empty($msg)) {
                    return $response->getBody()->write(\GuzzleHttp\json_encode($ary(10000, $msg)));
                }
            }
        }
        return $response->getBody()->write(\GuzzleHttp\json_encode($ary(0, '系统繁忙')));
    }

    private function step1($msg)
    {
        $res = $this->http->request('POST', 'http://weibo.com/aj/message/add?ajwvr=6&__rnd=1500179074690', [
            'headers' => $this->headerHandler(),
            'form_params' => $this->formHandler($msg),
        ]);

        $res1 = $res->getBody()->getContents();

        if ($res->getStatusCode() !== 200 || empty($res1)) {
            return false;
        }

        $res1 = \GuzzleHttp\json_decode($res1, true);

        if (is_array($res1)) {
            $code = $res1['code'];
            $html = $res1['data']['html'];
            if ($code == '100000') {
//                preg_match('#action\-data="mid=(\d*)">转发#', $html, $matches);
////                $this->logger->addDebug('mid:' . $matches[1]);
//                if (!empty($matches[1])) {
//                    return $matches[1];
//                }
                return true;
            }
        }
        return false;
    }

    private function step2()
    {
//        if (empty($mid))
//            return false;

        $ok = false;
        $requests = function ($total) use (&$ok) {
            $uri = "http://weibo.com/aj/message/getbyid?ajwvr=6&uid=5175429989&count=1&_t=0&__rnd=1500182066755";
            for ($i = 0; $i < $total; $i++) {
                $request = new Request('GET', $uri, $this->headerHandler());
//                if ($ok) {
//                    break;
//                }
                usleep(100000);
                yield $request;
            }
        };

        $pool = new Pool($this->http, $requests(15), [
            'concurrency' => 3,
            'fulfilled' => function ($response, $index) use (&$ok, &$result) {
                $response_ct = $response->getBody()->getContents();
                $response_ct = \GuzzleHttp\json_decode($response_ct, true);

                $code = $response_ct['code'];
                $html = $response_ct['data']['html'];
//                $this->logger->addDebug($html);
                if ($code == '100000') {
                    if (preg_match('#msg_bubble_list bubble_l#', $html)) {
                        if (!empty($split = $this->splitHtml($html))) {
                            $ok = true;
                            $this->logger->addInfo('收到消息：' . $split['content']);

                            if (!in_array($split, $this->messages->all())) {
                                $this->messages->set($index, $split);
                            }
                            return true;
                        }
                    }
                }
            },
            'rejected' => function ($reason, $index) use (&$ok) {
                $ok = true;
            },
        ]);

        $promise = $pool->promise();
        $promise->wait();

        return array_map(function ($item) {
            if ($item['type'] != 'text') {
                $path = $this->dl($item['content'], $item['extension'], $item['p']);
                $item['src'] = $item['content'];
                $item['content'] = $path;
            }
            return $item;
        }, array_values($this->messages->all()));
    }

    private function splitHtml($html)
    {
        $html = preg_replace('#[\s]#', '', $html);
        preg_match('#<!\-\-文本信息\-\->([\s\S]*)?<!\-\-／文本信息\-\-><!\-\-card信息\-\->([\s\S]*)<!\-\-／card信息\-\-><!\-\-附件信息\-\->([\s\S]*)<!\-\-／附件信息\-\->#', $html, $matches);


        if (!empty($matches[1])) {
            //txt
            return [
                'type' => 'text',
                'content' => mb_substr($matches[1], 15, -4),
            ];
        } elseif (!empty($matches[2])) {

        } elseif (!empty($matches[3])) {
            //music
            if (preg_match('#mes_acc_iconacc_icon_music#', $matches[3])) {
                preg_match('#<iclass="mes_acc_iconacc_icon_music"></i>--><spanclass="mes_acc_iconacc_icon_music"></span><spanclass="name">ttsvoice\.mp3.*</span><ahref="(.*)"class="download">下载</a></div>#', $matches[3], $mu_mtch);
                if (!empty($mu_mtch[1])) {
                    return [
                        'type' => 'music',
                        'extension' => 'mp3',
                        'content' => $mu_mtch[1],
                    ];
                }

            } elseif (preg_match('#ficon_download#', $matches[3])) {
                //image
                preg_match('#</i>收起</a></span></li><li><spanclass="line"><ahref="(.*)"><iclass="W_ficonficon_downloadS_ficon">\|</i>下载</a>#', $matches[3], $img_matches);

                if (!empty($img_matches[1])) {
                    return [
                        'type' => 'image',
                        'extension' => 'jpg',
                        'content' => $img_matches[1],
                    ];
                }
            }

        }
        return false;

    }

    private function dl($uri, $type, $filename = '', &$p)
    {
        $dir = 'storage/' . date('Ymd') . '/';
        $pub_dir = 'public/';
        if (empty($filename)) {
            $filename = $type . date('YmdHis') . rand(1, 9) . "." . $type;
        }
        $content = $this->http->request('GET', $uri, [
            'headers' => $this->headerHandler(),
            'connect_timeout' => '60'
        ])->getBody()->getContents();

        if (!file_exists(APP_ROOT . $dir)) {
            mkdir(APP_ROOT . $dir, 0777, true);
        }
        $bytes = @file_put_contents($p = APP_ROOT . $pub_dir . $dir . $filename, $content);

        $this->logger->addInfo('下载文件：' . $p . $bytes ?: '失败');

        return WEB_ROOT . $dir . $filename;
    }

    private function formHandler($msg)
    {
        if (!$msg) {
            return false;
        }
        $raw_forms = $this->files['forms'];
        $raw_form_ary = explode("\n", $raw_forms);
        $forms = array();
        foreach ($raw_form_ary as &$v) {
            if (($pos = strpos($v, ':')) !== false) {
                $name = mb_substr($v, 0, $pos);
                $value = mb_substr($v, $pos + 1);
                $forms[$name] = $value;
            }
        }
        $forms['text'] = $msg;
        return $forms;
    }

    private function headerHandler()
    {
        $raw_headers = $this->files['headers'];
        $raw_headers_ary = explode("\n", $raw_headers);
        $headers = array();
        foreach ($raw_headers_ary as &$v) {
            if (($pos = strpos($v, ':')) !== false) {
                $name = mb_substr($v, 0, $pos);
                $value = mb_substr($v, $pos + 1);
                $headers[$name] = $value;
            }
        }
        return $headers;
    }


}
